package benchmarkapplication;

import entitydao.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ThreadTest implements Runnable {

    QuerySet mQuerySet;
    QuerySetPool mQuerySetPool;
    int mThreadId;
    int queryNumber;
    int index;

    public ThreadTest(int threadId, QuerySet querySet, QuerySetPool querySetPool) {
        mQuerySet = querySet;
        mThreadId = threadId;
        mQuerySetPool = querySetPool;
    }

    public void run() {
        String nl = "\n";
        if (mThreadId % 3 == 0) {
            nl = "";
        }
        System.out.print("#" + mThreadId + " : Start \t" + nl);

        Random rnd = new Random(mThreadId);
        int i = 0;

        while (true) {
            try {
                TableDAO tableObject = mQuerySet.GetTableObject(this);
                Method method = mQuerySetPool.GetQueryMethod(index);
                String methodName = method.getName();
                // check when the number of the query were be executed
                if (mQuerySetPool.CanIExecuteQuery(index, this) == false) {
                    if (mQuerySetPool.CanIFinish()) {
                        break;
                    }
                    continue;
                } // prepare parameters
                int count = mQuerySetPool.GetMethodParameters(index).length;
                Object[] parameters = new Object[count];
                for (int j = 0; j < count; j++) {
                    int randIndex;
                    if (tableObject.getClass() == AutorDAO.class) {
                        if (methodName.equals("findById")) {
                            randIndex = rnd.nextInt(QuerySetPool.AUTOR_COUNT);
                            parameters[j] = mQuerySetPool.getAutorAt(randIndex).getId_autor();
                        }
                        if (methodName.equals("findBySurname")) {
                            randIndex = rnd.nextInt(QuerySetPool.AUTOR_COUNT);
                            parameters[j] = mQuerySetPool.getAutorAt(randIndex).getPrijmeni();
                        }
                        if (methodName.equals("insertAutor")) {
                            parameters[j] = mQuerySetPool.getAutor();
                        }
                        if (methodName.equals("delete")) {
                            randIndex = rnd.nextInt(QuerySetPool.AUTOR_COUNT);
                            parameters[j] = mQuerySetPool.getAutorAt(randIndex).getId_autor();
                        }
                    }
                    if (tableObject.getClass() == KnihaDAO.class) {
                        if (methodName.equals("findById")) {
                            randIndex = rnd.nextInt(QuerySetPool.KNIHA_COUNT);
                            parameters[j] = mQuerySetPool.getKnihaAt(randIndex).getId_kniha();
                        }
                        if (methodName.equals("findByNazev")) {
                            randIndex = rnd.nextInt(QuerySetPool.KNIHA_COUNT);
                            parameters[j] = mQuerySetPool.getKnihaAt(randIndex).getNazev();
                        }
                        if (methodName.equals("delete")) {
                            randIndex = rnd.nextInt(QuerySetPool.KNIHA_COUNT);
                            parameters[j] = mQuerySetPool.getKnihaAt(randIndex);
                        }
                        if (methodName.equals("insert")) {
                            parameters[j] = mQuerySetPool.getKniha();
                        }
                    }
                    if (tableObject.getClass() == NakladatelstviDAO.class) {
                        if (methodName.equals("findById")) {
                            randIndex = rnd.nextInt(QuerySetPool.NAKLADATELSTVI_COUNT);
                            parameters[j] = mQuerySetPool.getNaklAt(randIndex).getId_nakladatelstvi();
                        }
                        if (methodName.equals("findByNazev")) {
                            randIndex = rnd.nextInt(QuerySetPool.NAKLADATELSTVI_COUNT);
                            parameters[j] = mQuerySetPool.getNaklAt(randIndex).getNazev();
                        }
                        if (methodName.equals("findByMesto")) {
                            randIndex = rnd.nextInt(QuerySetPool.NAKLADATELSTVI_COUNT);
                            parameters[j] = mQuerySetPool.getNaklAt(randIndex).getMesto();
                        }
                        if (methodName.equals("insert")) {
                            parameters[j] = mQuerySetPool.getNakladatelstvi();
                        }
                    }
                    if (tableObject.getClass() == NavstevnikDAO.class) {
                        if (methodName.equals("findById")) {
                            randIndex = rnd.nextInt(QuerySetPool.NAVSTEVNIK_COUNT);
                            parameters[j] = mQuerySetPool.getNavstevnikAt(randIndex).getId_navstevnik();
                        }
                        if (methodName.equals("findByMail")) {
                            randIndex = rnd.nextInt(QuerySetPool.NAVSTEVNIK_COUNT);
                            parameters[j] = mQuerySetPool.getNavstevnikAt(randIndex).getMail();
                        }
                        if (methodName.equals("findByLogin")) {
                            randIndex = rnd.nextInt(QuerySetPool.NAVSTEVNIK_COUNT);
                            parameters[j] = mQuerySetPool.getNavstevnikAt(randIndex).getLogin();
                        }
                        if (methodName.equals("insert")) {
                            parameters[j] = mQuerySetPool.getNavstevnik();
                        }
                        if (methodName.equals("delete")) {
                            randIndex = rnd.nextInt(QuerySetPool.NAVSTEVNIK_COUNT);
                            parameters[j] = mQuerySetPool.getNavstevnikAt(randIndex);
                        }
                        if (methodName.equals("updateMail")) {
                            randIndex = rnd.nextInt(QuerySetPool.NAVSTEVNIK_COUNT);
                            parameters[0] = mQuerySetPool.getNavstevnik().getMail();
                            parameters[1] = mQuerySetPool.getNavstevnikAt(randIndex).getLogin();
                        }
                        if (methodName.equals("updatePass")) {
                            randIndex = rnd.nextInt(QuerySetPool.NAVSTEVNIK_COUNT);
                            parameters[0] = mQuerySetPool.getNavstevnik().getPass();
                            parameters[1] = mQuerySetPool.getNavstevnikAt(randIndex).getLogin();
                        }
                    }
                    if (tableObject.getClass() == PujcenoDAO.class) {
                        if (methodName.equals("findByNavstevnik")) {
                            randIndex = rnd.nextInt(QuerySetPool.PUJCENO_COUNT);
                            parameters[j] = mQuerySetPool.getPujcenoAt(randIndex).getNavstevnik();
                        }
                        if (methodName.equals("findByKniha")) {
                            randIndex = rnd.nextInt(QuerySetPool.PUJCENO_COUNT);
                            parameters[j] = mQuerySetPool.getPujcenoAt(randIndex).getKniha();
                        }
                        if (methodName.equals("insert")) {
                            parameters[j] = mQuerySetPool.getPujceno();
                        }
                        if (methodName.equals("delete")) {
                            randIndex = rnd.nextInt(QuerySetPool.PUJCENO_COUNT);
                            parameters[j] = mQuerySetPool.getPujcenoAt(randIndex);
                        }
                    }
                    //Tady dodělat a ošetřit další parametry
                }
                method.invoke(tableObject, parameters);
                // print only sometimes, for performance reason
                if (i++ % 10 == 0) {
                    System.out.println("#" + mThreadId + " (" + methodName + "): " + queryNumber);
                }
                if (mQuerySetPool.CanIFinish()) {
                    break;
                }
            } catch (IllegalAccessException ex) {
                Logger.getLogger(ThreadTest.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(ThreadTest.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvocationTargetException ex) {
                Logger.getLogger(ThreadTest.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        System.out.print("#" + mThreadId + " : End \t");
    }
}
